home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / misc / pdflib / p_image.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  7KB  |  306 lines

  1. /* p_image.c
  2.  * Copyright (C) 1997-98 Thomas Merz. All rights reserved.
  3.  *
  4.  * PDFlib image routines
  5.  */
  6.  
  7. #include <stdio.h>
  8.  
  9. #include "p_intern.h"
  10.  
  11. void
  12. PDF_place_image(PDF *p, PDF_image *image, float x, float y, float scale)
  13. {
  14.     PDF_put_image(p, image);
  15.     PDF_execute_image(p, image, x, y, scale);
  16. }
  17.  
  18. void
  19. PDF_put_image(PDF *p, PDF_image *image)
  20. {
  21.     PDF_data_source    src;
  22.  
  23.     id            image_id, length_id, colormap_id = 0;
  24.     long        length;
  25.  
  26.     switch (image->colorspace) {
  27.         case DeviceGray:
  28.         case DeviceRGB:
  29.         case DeviceCMYK:
  30.         break;
  31.  
  32.     default:
  33.         pdf_error(p, PDF_INTERNAL, "Bad number of color components");
  34.         break;
  35.     }
  36.  
  37.     pdf_end_contents_section(p);
  38.  
  39.     /* Write colormap information for indexed color spaces */
  40.     if (image->indexed) {
  41.     colormap_id = pdf_begin_obj(p, NEW_ID);    /* Colormap object */
  42.     pdf_begin_dict(p);         
  43.         if (!p->info->binary_mode) {
  44. #ifdef DEBUG
  45.         (void) fputs("/Filter [/ASCIIHexDecode]\n", p->fp);
  46. #else
  47.         (void) fputs("/Filter [/ASCII85Decode]\n", p->fp);
  48. #endif
  49.         }
  50.  
  51.         /* Length of colormap object */
  52.         length_id = pdf_alloc_id(p);
  53.         (void) fprintf(p->fp,"/Length %ld 0 R\n", length_id);
  54.     pdf_end_dict(p);
  55.  
  56.     pdf_begin_stream(p);
  57.     p->start_contents_pos = ftell(p->fp);
  58.  
  59.     if (image->components != 1 && image->components != 3) {
  60.         pdf_error(p, PDF_FATAL, "Bogus indexed colorspace");
  61.     }
  62.  
  63.     /* Write colormap data */
  64.     if (!p->info->binary_mode) {
  65.         /* use another data source than GIF image data source! */
  66.         PDF_data_source_from_buf(p, &src, (byte *) image->colormap,
  67.         (long) image->BitPixel * 3);     /* HACK */
  68. #ifdef DEBUG
  69.         pdf_ASCIIHexEncode(p, &src);
  70. #else
  71.         pdf_ASCII85Encode(p, &src);
  72. #endif
  73.     } else {
  74.         fwrite(image->colormap, image->BitPixel * 3, 1, p->fp);     /* HACK */
  75.         (void) fputs("\n", p->fp);
  76.     }
  77.  
  78.     length = ftell(p->fp) - p->start_contents_pos;
  79.  
  80.     pdf_end_stream(p);
  81.     pdf_end_obj(p);
  82.  
  83.     pdf_begin_obj(p, length_id);        /* Length object for colormap */
  84.     (void) fprintf(p->fp,"%ld\n", length);
  85.     pdf_end_obj(p);
  86.     }
  87.  
  88.     image_id = pdf_begin_obj(p, NEW_ID);    /* Image object */
  89.     pdf_add_res_xobject(p, image_id);
  90.  
  91.     length_id        = pdf_alloc_id(p);
  92.  
  93.     pdf_begin_dict(p);         
  94.  
  95.     image->no = p->image_number++;
  96.     (void) fputs("/Type /XObject\n", p->fp);
  97.     (void) fputs("/Subtype /Image\n", p->fp);
  98.     (void) fprintf(p->fp,"/Name /I%d\n", image->no);
  99.     (void) fprintf(p->fp,"/Width %d\n", image->width);
  100.     (void) fprintf(p->fp,"/Height %d\n", image->height);
  101.     (void) fprintf(p->fp,"/BitsPerComponent %d\n", image->bpc);
  102.  
  103.     (void) fputs("/ColorSpace ", p->fp);
  104.     if (image->indexed) {
  105.     (void) fputs("[/Indexed ", p->fp);
  106.     (void) fprintf(p->fp, "/%s %d %ld 0 R ]\n",
  107.         (image->components == 3 || image->indexed ? 
  108.         pdf_colorspace_names[DeviceRGB] :
  109.         pdf_colorspace_names[DeviceGray]),
  110.         image->BitPixel - 1, colormap_id);
  111.     } else {
  112.     (void) fprintf(p->fp, "/%s\n", pdf_colorspace_names[image->colorspace]);
  113.     }
  114.  
  115.     /* do we need a Filter (either ASCII or decompression)? */
  116.     if (!p->info->binary_mode || image->compression != none)
  117.     (void) fputs("/Filter [", p->fp);
  118.  
  119.     if (!p->info->binary_mode) {
  120. #ifdef DEBUG
  121.     (void) fputs("/ASCIIHexDecode ", p->fp);
  122. #else
  123.     (void) fputs("/ASCII85Decode ", p->fp);
  124. #endif
  125.     }
  126.  
  127.     if (image->compression != none)
  128.     (void) fprintf(p->fp, "/%s", pdf_filter_names[image->compression]);
  129.  
  130.     if (!p->info->binary_mode || image->compression != none)
  131.     (void) fprintf(p->fp, "]\n");
  132.  
  133.     if (image->compression == lzw) {
  134.     if (p->info->binary_mode)
  135.         (void) fprintf(p->fp, "/DecodeParms <</EarlyChange 0>>\n");
  136.     else
  137.         (void) fprintf(p->fp, 
  138.         "/DecodeParms [ null <</EarlyChange 0>>]\n");
  139.     }
  140.  
  141.     (void) fprintf(p->fp,"/Length %ld 0 R\n", length_id);
  142.     pdf_end_dict(p);
  143.  
  144.     pdf_begin_stream(p);
  145.     p->start_contents_pos = ftell(p->fp);
  146.  
  147.     /* image data */
  148.     if (p->info->binary_mode)
  149.     {
  150.     image->src.init(p, &image->src);
  151.  
  152.     while (image->src.fill(p, &image->src)) {
  153.         (void) fwrite(image->src.next_byte, 1, 
  154.             image->src.bytes_available, p->fp);
  155.     }
  156.     image->src.terminate(p, &image->src);
  157.     }
  158.     else
  159.     {
  160. #ifdef DEBUG
  161.     pdf_ASCIIHexEncode(p, &image->src);
  162. #else
  163.     pdf_ASCII85Encode(p, &image->src);
  164. #endif
  165.     }
  166.  
  167.     length = ftell(p->fp) - p->start_contents_pos;
  168.  
  169.     pdf_end_stream(p);
  170.     pdf_end_obj(p);
  171.  
  172.     pdf_begin_obj(p, length_id);        /* Length object */
  173.     (void) fprintf(p->fp,"%ld\n", length);
  174.     pdf_end_obj(p);
  175. }
  176.  
  177. /* Section 8.8 XObject operator */
  178.  
  179. void
  180. PDF_execute_image(PDF *p, PDF_image *image, float x, float y, float scale)
  181. {
  182.     PDF_matrix m;
  183.  
  184.     if (scale == 0.0) {
  185.     pdf_error(p, PDF_FATAL, "Scale factor 0 for image %s", image->filename);
  186.     return;
  187.     }
  188.  
  189.     if (image->components == 3 || image->indexed)
  190.     p->res.procset    |= ImageC;
  191.     else
  192.     p->res.procset    |= ImageB;
  193.  
  194.     pdf_end_text(p);
  195.     pdf_begin_contents_section(p);
  196.  
  197.     PDF_save(p);
  198.  
  199.     m.a = image->width * scale;
  200.     m.d = image->height * scale;
  201.     m.b = m.c = 0.0;
  202.     m.e = x;
  203.     m.f = y;
  204.     pdf_concat(p, m);
  205.  
  206.     /* todo: image name */     /* HACK */
  207.     (void) fprintf(p->fp,"/I%d Do\n", image->no);
  208.  
  209.     PDF_restore(p);
  210. }
  211.  
  212. /* Section 8.9 In-line image operators */
  213.  
  214. void
  215. PDF_place_inline_image(PDF *p, PDF_image *image, float x, float y, float scale)
  216. {
  217.     PDF_matrix m;
  218.  
  219.     p->res.procset |= (image->colorspace == DeviceGray ? ImageB : ImageC);
  220.  
  221.     pdf_end_text(p);
  222.     PDF_save(p);
  223.  
  224.     m.a = image->width * scale;
  225.     m.d = image->height * scale;
  226.     m.b = m.c = 0.0;
  227.     m.e = x;
  228.     m.f = y;
  229.  
  230.     pdf_concat(p, m);
  231.  
  232.     (void) fputs("BI\n", p->fp);
  233.     (void) fprintf(p->fp,"/W %d\n", image->width);
  234.     (void) fprintf(p->fp,"/H %d\n", image->height);
  235.     (void) fprintf(p->fp,"/BPC %d\n", image->bpc);
  236.  
  237.     (void) fputs("/CS ", p->fp);
  238.     switch (image->colorspace) {
  239.     case DeviceGray:
  240.         if (image->components != 1)
  241.         pdf_error(p, PDF_FATAL,
  242.             "Invalid number of color components for /DeviceGray!");
  243.         (void) fputs("/G\n", p->fp);
  244.         break;
  245.  
  246.     case DeviceRGB:
  247.         if (image->components != 3)
  248.         pdf_error(p, PDF_FATAL, 
  249.             "Invalid number of color components for /DeviceRGB!");
  250.         (void) fputs("/RGB\n", p->fp);
  251.         break;
  252.  
  253.     case DeviceCMYK:
  254.         if (image->components != 4)
  255.         pdf_error(p, PDF_FATAL, 
  256.             "Invalid number of color components for /DeviceCMYK!");
  257.         (void) fputs("/CMYK\n", p->fp);
  258.         break;
  259.  
  260.     case Indexed:
  261.         pdf_error(p, PDF_FATAL,
  262.             "Indexed color space for inline images NYI!");
  263.         break;
  264.  
  265.     default:
  266.         pdf_error(p, PDF_FATAL,
  267.             "Unknown color space for inline images!");
  268.         break;
  269.     }
  270.  
  271.     if (!p->info->binary_mode)
  272. #ifdef DEBUG
  273.     (void) fputs("/F /AHx\n", p->fp);
  274. #else
  275.     (void) fputs("/F /A85\n", p->fp);
  276. #endif
  277.     (void) fputs("ID ", p->fp);
  278.  
  279.     if (p->info->binary_mode)
  280.     {
  281.     image->src.init(p, &image->src);
  282.     while (image->src.fill(p, &image->src)) {
  283.         (void) fwrite(image->src.next_byte, 1, 
  284.             image->src.bytes_available, p->fp);
  285.     }
  286.     image->src.terminate(p, &image->src);
  287.     }
  288.     else
  289.     {
  290. #ifdef DEBUG
  291.     pdf_ASCIIHexEncode(p, &image->src);
  292. #else
  293.     pdf_ASCII85Encode(p, &image->src);
  294. #endif
  295.     }
  296.  
  297.     (void) fputs("EI\n", p->fp);
  298.     PDF_restore(p);
  299. }
  300.  
  301. void
  302. PDF_close_image(PDF *p, PDF_image *image)
  303. {
  304.     image->closefunc(p, image);
  305. }
  306.